using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;

namespace Universe.Threading.Test
{
    class Program
    {
        static int JobWeight = 200;

        static void Main(string[] args)
        {

            
            Stopwatch sw;
            long msec;

            SampleJob(0, 1);
            Parallel.ForEach(new int[] { 1 }, SampleJob);
            Parallel.ForEach(new int[] { 1 }, 1, SampleJob);
            Parallel.ForEach(new int[] { 1 }, 2, SampleJob);
            Parallel.ForEach(new int[] { 1 }, 2, 2, SampleJob);


            // int[] weights = new int[] { 1, 10, 100, 200, 500, 1000 };
            int[] weights = new int[] { 1, 10, 100, 200 };
            foreach (int weight in weights)
            {
                JobWeight = weight;
                int arrayLength = 1000000/JobWeight;
                IEnumerable<int> array = RangeFor<int>.Forward(0, arrayLength);

                sw = new Stopwatch();
                sw.Start();
                int index = 0;
                foreach (int i in array)
                    SampleJob(index++, i);

                msec = sw.ElapsedMilliseconds;
                long msec0 = msec;
                Console.WriteLine("ITERATION WEIGHT: {0:f3} msec", 1d * msec / arrayLength);
                Console.WriteLine("Single thread: {0} msec", msec);

                sw = new Stopwatch();
                sw.Start();
                Parallel.ForEach(array, SampleJob);
                msec = sw.ElapsedMilliseconds;
                Console.WriteLine("All Thread Pool Threads: {0} msec, scale: {1:f3}", msec, 1d * msec0 / msec);

                // Console.ReadLine();
                int[] tcs = new int[] {1, 2, 3, 4, 8, 16, 32, 64};
                foreach (int num in tcs)
                {
                    sw = new Stopwatch();
                    sw.Start();
                    Parallel.ForEach(array, num, 1000, SampleJob);
                    msec = sw.ElapsedMilliseconds;
                    Console.WriteLine("{1,3} Thread(s): {0} msec, scale: {2:f3}", msec, num, 1d * msec0 / msec);
                    // Console.ReadLine();
                }

                Console.WriteLine();
            }
        }

        static void SampleJob(int index, int element)
        {
            for (int j = 0; j < JobWeight; j++)
            {
                string v = string.Format("{0,6} {1:f5}", 1, Math.PI * 2d + (double)j);
            }
        }

    }
}
